using System;
using System.Collections.Generic;

namespace FrameWork
{
    /// <summary>
    /// 事件Module
    /// 注意,可以像GameFrameWork那样进行扩展EventPool<T>
    /// 这里简单使用
    /// </summary>
    public sealed partial class EventModule : BaseModule
    {
        public delegate void SimpleEventHandler<T>(T e);

        //public delegate void SimpleEventHandler(EventArgs e);

        private Dictionary<int, SimpleEventHandler<EventArgs>> _eventDic;

        private Queue<Event> _eventQueue;

        public override void Init()
        {
            _eventDic = new Dictionary<int, SimpleEventHandler<EventArgs>>();
            _eventQueue = new Queue<Event>();
        }

        /// <summary>
        /// 添加监听
        /// </summary>
        public void AddEventListener(int eventId, SimpleEventHandler<EventArgs> callBack)
        {
            if (!_eventDic.ContainsKey(eventId))
            {
                _eventDic.Add(eventId, callBack);
            }
            else
            {
                Delegate.Combine(_eventDic[eventId], callBack);
            }
        }

        /// <summary>
        /// 移除监听
        /// </summary>
        public void RemoveEventListener(int eventId, SimpleEventHandler<EventArgs> callBack)
        {
            if (!_eventDic.ContainsKey(eventId))
                return;

            Delegate.Remove(_eventDic[eventId], callBack);
        }

        /// <summary>
        /// 仅发送int id事件
        /// </summary>
        public void FireEvent(int eventId)
        {
            if (!_eventDic.ContainsKey(eventId))
                return;

            EventArgs baseEventArgs = new EventArgs();
            var baseEvent = Event.Create(eventId, baseEventArgs);
            _eventQueue.Enqueue(baseEvent);
        }

        /// <summary>
        /// 发送带信息的事件
        /// </summary>
        public void FireEvent(int eventId,EventArgs eventArgs)
        {
            var baseEvent = Event.Create(eventId, eventArgs);
            _eventQueue.Enqueue(baseEvent);
        }

        public override void ShutDown()
        {
            if(_eventDic.Count > 0)
            {
                _eventDic.Clear();
            }
            
            if(_eventQueue.Count > 0)
            {
                _eventQueue.Clear();
            }
        }

        /// <summary>
        /// 每一帧处理事件
        /// </summary>
        public override void Update(float deltaTime, float realDeltaTime)
        {
            lock (_eventQueue)
            {
                while (_eventQueue.Count > 0)
                {
                    var deEvent = _eventQueue.Dequeue();
                    int eventId = deEvent.EventId;
                    var handler = _eventDic[eventId];
                    handler?.Invoke(deEvent.EventArgs);
                    ReferencePool.Recycle(deEvent);
                }
            }
        }
    }
}

